home *** CD-ROM | disk | FTP | other *** search
/ PC Graphics Unleashed / PC Graphics Unleashed.iso / ch21 / bezier.c < prev    next >
C/C++ Source or Header  |  1994-08-08  |  3KB  |  151 lines

  1. ///////////////////////////////
  2. //
  3. // CODE TO DRAW A BEZIER CURVE
  4. // BEZIER.C
  5. //
  6. //////////////////////////////
  7.  
  8. #include <dos.h>
  9. #include <graphics.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <conio.h>
  13. #include <math.h>
  14.  
  15.  
  16. typedef struct {
  17.   float x,y;
  18. } Point2D;
  19.  
  20. void InitGraphics(void);
  21. void WorldToDevice(float wx, float wy, int * dx, int * dy);
  22. void DrawAPoint2D(Point2D p);
  23. void DrawALine(Point2D p1, Point2D p2);
  24. float Bernstein(int c, float u);
  25.  
  26.  
  27. float  WxLeft, WxRight, WyTop, WyBottom;
  28. int    DyMax, DxMax, DyMin, DxMin;
  29.  
  30.  
  31. void main(void)
  32. {
  33.  int i;
  34.  float t, B, step;
  35.  Point2D c, c_old, pnt, p[4];
  36.  
  37.  InitGraphics();
  38.  
  39.  WxLeft   = -3;
  40.  WxRight  =  3;
  41.  WyTop    =  3;
  42.  WyBottom = -3;
  43.  
  44.  DyMin = 0;
  45.  DxMin = 0;
  46.  DyMax = getmaxy();
  47.  DxMax = getmaxy();
  48.  
  49.  
  50.  setviewport((getmaxx()-getmaxy())/2,0,getmaxx(),getmaxy(),1);
  51.  
  52.  setbkcolor(WHITE);
  53.  cleardevice();
  54.  setcolor(BLUE);
  55.  
  56.  p[0].x = -1.0;
  57.  p[0].y =  0.0;
  58.  
  59.  p[1].x = -0.3;
  60.  p[1].y =  2.0;
  61.  
  62.  p[2].x =  0.3;
  63.  p[2].y =  -2.0;
  64.  
  65.  p[3].x =  1.0;
  66.  p[3].y =  0.0;
  67.  
  68.  DrawAPoint2D(p[0]);
  69.  DrawAPoint2D(p[1]);
  70.  DrawAPoint2D(p[2]);
  71.  DrawAPoint2D(p[3]);
  72.  DrawALine(p[0], p[1]);
  73.  DrawALine(p[1], p[2]);
  74.  DrawALine(p[2], p[3]);
  75.  
  76.  setlinestyle(SOLID_LINE, 1, 3);
  77.  step = 20.0;
  78.  for(t=0; t<=(int)step; t++) {
  79.    c.x = c.y = 0.0;
  80.    for(i=0;i<=3;i++) {
  81.  
  82.       B = Bernstein(i,t/step);
  83.       c.x += p[i].x * B;
  84.       c.y += p[i].y * B;
  85.  
  86.    }
  87.    if(!t) c_old = c;
  88.    else {
  89.       DrawALine(c_old, c);
  90.       c_old = c;
  91.    }
  92.  }
  93.  getch();
  94.  closegraph();
  95. }
  96.  
  97. /* ================================================================== */
  98.  
  99. float Bernstein(int c, float u) {
  100.    switch(c) {
  101.       case 0: return (pow((1.0-u),3));
  102.       case 1: return (3.0 * u * pow((1.0-u),2));
  103.       case 2: return (3.0 * pow(u,2) * (1.0-u));
  104.       default: return (pow(u,3));
  105.    }
  106. }
  107.  
  108. void WorldToDevice(float wx, float wy, int * dx, int * dy) {
  109.     *dx = (WxLeft - wx) * DxMax / (WxLeft - WxRight);
  110.     *dy = (WyTop - wy) * DyMax / (WyTop - WyBottom);
  111. }
  112.  
  113. void DrawAPoint2D(Point2D p) {
  114.   int dx, dy;
  115.   WorldToDevice(p.x, p.y, &dx, &dy);
  116.   rectangle(dx-2,dy-2,dx+2,dy+2);
  117. }
  118.  
  119. void DrawALine(Point2D p1, Point2D p2) {
  120.   int dx1, dy1, dx2, dy2;
  121.   WorldToDevice(p1.x, p1.y, &dx1, &dy1);
  122.   WorldToDevice(p2.x, p2.y, &dx2, &dy2);
  123.   line(dx1,dy1,dx2,dy2);
  124. }
  125.  
  126.  
  127. void InitGraphics(void)
  128. {
  129.  int gdriver = DETECT, gmode, errorcode;
  130.  initgraph(&gdriver, &gmode, "");
  131.  errorcode = graphresult();
  132.  if (errorcode != grOk)  /* an error occurred */
  133.  {
  134.    printf("Graphics error: %s\n", grapherrormsg(errorcode));
  135.    printf("Press any key to halt:");
  136.    getch();
  137.    exit(1); /* terminate with an error code */
  138.  }
  139.  setviewport(0,0,getmaxx(),getmaxy(),1);
  140. }
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.